package sfy.md.netty.netty;

import ch.qos.logback.classic.net.SimpleSocketServer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.net.InetSocketAddress;

public class EchoServer {

    private final int port;
    public EchoServer(int port) {
        this.port = port;
    }
    public void start() throws Exception {
        //使用NIO事件循环组来接受和处理新的连接， OIO可以使用OioEventLoopGroup()
        //线程池  接受请求
        NioEventLoopGroup acceptGroup = new NioEventLoopGroup();

        //处理任务
        NioEventLoopGroup taskGroup = new NioEventLoopGroup();
        try {
            //ServerBootstrap 是一个启动NIO服务的辅助启动类 你可以在这个服务中直接使用Channel
            ServerBootstrap b = new ServerBootstrap();
            //#1
            //这一步是必须的，如果没有设置group将会报java.lang.IllegalStateException: group not set异常
            b.group(acceptGroup,taskGroup)                                                      //#2
                    //指定NIO传输类型
                    .channel(NioServerSocketChannel.class)
                    .handler(new SimpleServerHandler())
                    //本地套接字地址
                    .localAddress(new InetSocketAddress(port))                    //#2

                    //把处理器加入到channel pipeline
                    .childHandler(new ChannelInitializer<SocketChannel>() {       //#3
                        //每个连接上一个连接调用一次
                        @Override
                        public void initChannel(SocketChannel ch)
                                throws Exception {
                            //设置childHandler执行所有的连接请求
                            ch.pipeline().addLast(new EchoServerHandler());      //#4
                        }
                    });
            //异步绑定服务器，sync()方法的调用将引起这个阻塞，直到服务器绑定完成.
            ChannelFuture f = b.bind().sync();                                    //#5
            System.out.println(EchoServer.class.getName() +                       //#6
                    " started and listen on " + f.channel().localAddress());      //#7
            //应用程序将一直等待，直到服务器的通道关闭(因为我们在通道的close future上调用了sync())
            f.channel().closeFuture().sync();                                     //#8
        } finally {                                                               //#9
            //释放所有的资源
            acceptGroup.shutdownGracefully().sync();//#10
            taskGroup.shutdownGracefully().sync();//#11
        }
    }

    private static class SimpleServerHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            System.out.println("channelActive");
        }

        @Override
        public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
            System.out.println("channelRegistered");
        }

        @Override
        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
            System.out.println("handlerAdded");
        }
    }

    public static void main(String[] args) throws Exception {
        new EchoServer(8080).start();
    }
}


